#include <iostream>
#include <thread>
#include <chrono>

#include "client.h"
#include "hv/hlog.h"
#include "hv/hloop.h"
#include "hv/hsocket.h"

#define PACK_LEN 20 * 1024 - 1
//#define PACK_LEN 1024 * 1024 - 1

static void on_close(hio_t *io) {
    LOGW("[ C ] connection closed, fd: %d, error: %s", hio_fd(io), hio_error(io));
}

static void on_recv(hio_t *io, void *buf, int readbytes) {
    LOGI("[ C ] recv. fd: %d, readbytes: %d", hio_fd(io), readbytes);
}

static void on_write(hio_t *io, const void *buf, int wbytes) {
    LOGI("[ C ] written. fd: %d, written bytes: %d", hio_fd(io), wbytes);
}

static void on_connect(hio_t *io) {
    char localaddrstr[SOCKADDR_STRLEN] = {0};
    char peeraddrstr[SOCKADDR_STRLEN] = {0};

    LOGI("[ C ] connected, fd: %d [%s] => [%s]", hio_fd(io),
        SOCKADDR_STR(hio_localaddr(io), localaddrstr),
        SOCKADDR_STR(hio_peeraddr(io), peeraddrstr)
    );

    hio_setcb_close(io, on_close);
    hio_setcb_read(io, on_recv);
    hio_setcb_write(io, on_write);
    hio_read(io);

    char msg[PACK_LEN] = {0};
    int i;
    for (i = 0; i < PACK_LEN - 1; i++) msg[i] = 'a';
    int body_len = strlen(msg);

    hio_write(io, &body_len, sizeof(int));
    hio_write(io, msg, body_len/2);
    hio_write(io, msg + body_len/2, body_len/2);
}

void cmain(uint16_t port) {
    hloop_t *loop = hloop_new(0);

    hio_t *io = create_tcp_client(loop, "127.0.0.1", port, on_connect);
    if (io == NULL) {
        LOGE("[ C ] Failed create_tcp_client.");
    } else {
        LOGI("[ C ] connect to port: %d, fd: %d", port, hio_fd(io));
        hloop_run(loop);
    }

    //std::this_thread::sleep_for (std::chrono::seconds(1));

    hloop_free(&loop);

    LOGI("[ C ] Exit.");
}
